// docxWorker.ts
// 用 ES Module worker: new Worker(new URL('./docxWorker.ts', import.meta.url), { type: 'module' })

import Docxtemplater from "docxtemplater";
import PizZip from "pizzip";

export type RenderTask = {
  id: string; // 任务 id
  templateBuffer: ArrayBuffer; // 复用的模板二进制
  data: Record<string, unknown>; // 模板数据
};

export type RenderResult =
  | { id: string; ok: true; arrayBuffer: ArrayBuffer }
  | { id: string; ok: false; error: string };

self.onmessage = async (e: MessageEvent<RenderTask>) => {
  const { id, templateBuffer, data } = e.data;
  try {
    // 1) 解析模板
    const zip = new PizZip(templateBuffer);
    const doc = new Docxtemplater(zip, {
      paragraphLoop: true,
      linebreaks: true,
      nullGetter: () => "", // 避免缺字段直接抛错
    });

    // 2) 渲染
    doc.setData(data);
    doc.render();

    // 3) 生成 ArrayBuffer（可作为 transferable 直接转移，减少拷贝）
    const arrayBuffer: ArrayBuffer = await doc.getZip().generate({
      type: "arraybuffer",
      mimeType:
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      compression: "DEFLATE", // 适度压缩，体积更小
    });

    // 4) 回传结果（transfer 以减少内存拷贝）
    (self as unknown as Worker).postMessage(
      { id, ok: true, arrayBuffer } as RenderResult,
      [arrayBuffer] // Transferable
    );
  } catch (err: any) {
    const explanation =
      err?.properties?.errors
        ?.map((x: any) => x.properties?.explanation)
        .join("\n") || err?.message || String(err);
    (self as unknown as Worker).postMessage({ id, ok: false, error: explanation } as RenderResult);
  }
};
